# -*- coding: utf-8 -*-

from PyQt4.QtCore import QCoreApplication, QEventLoop
import getopt, os, sys, shlex
from operator import itemgetter
from subprocess import *
import sqlite3 as sqlite

LOGLIMIT = 100

defaultDirectory = ""

connection = sqlite.connect('commits.db')
cursor = connection.cursor()

def getGitRepo(serverUrl, projectDirectory, browser):    
    browser.clear()

    global defaultDirectory
    defaultDirectory = os.getcwd()

    if os.path.exists(projectDirectory):
        browser.append("Destination already exists!... Will UPDATE:\n\n%s" % serverUrl + "\n\nHold on please...\n\n\n")
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

        os.chdir(projectDirectory)
        proc = Popen("git fetch origin", shell=True, stdout=PIPE)
        while True:
            out = proc.stdout.readline()
            if out == '' and proc.poll() != None:
                break
            if out != '':
                out = out.replace('\n', '')
                browser.append(out)
                QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
                
        proc = Popen("git reset --hard origin", shell=True, stdout=PIPE)
        while True:
            out = proc.stdout.readline()
            if out == '' and proc.poll() != None:
                break
            if out != '':
                out = out.replace('\n', '')
                browser.append(out)
                QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)        

    else:
        os.system("mkdir " + projectDirectory)
        os.chdir(projectDirectory)
	browser.append("Starting to CHECKOUT:\n\n%s" % serverUrl + "\n\nHold on please...\n\n\n")
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

        proc = Popen("git clone %s" % serverUrl, shell=True, stdout=PIPE)
        while True:
            out = proc.stdout.readline()
            if out == '' and proc.poll() != None:
                break
            if out != '':
                out = out.replace('\n', '')
                browser.append(out)
                QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    os.chdir(defaultDirectory)
     
def parseGitLog(projectName, projectVersion, filePath, browser):
    browser.clear()

    if not os.path.exists(filePath):
        browser.append("%s does not exist" % filePath)
        return

    global defaultDirectory
    defaultDirectory = os.getcwd()

    os.chdir(filePath)

    fileDict = {}
    authorDict = {}
    logDict = {}
    proc = Popen('git log --pretty=format:"%h|%an|%ai" .', shell=True, stdout=PIPE)
    log = proc.stdout.readlines()
    endDate = None
    numberOfFiles = 0

    for root, dirs, files in os.walk("."):
        for file in files:
            numberOfFiles += 1

    if not log:
        browser.append("Failed to read the log for %s" % filePath)
        return
    else:
        startDate = " ".join((log[-1].strip().split("|")[-1]).split(" ")[:-1])
        endDate = " ".join((log[0].strip().split("|")[-1]).split(" ")[:-1])

        for line in log:
            (commit, author, time) = line.strip().split("|")

            logDict[commit] = {}
            logDict[commit]["author"] = author
            logDict[commit]["time"] = " ".join(time.split(" ")[:-1])

    i = 1
    for key in logDict.keys():
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
        browser.append("PROCESSING:\tCommit %s/%d..." % (str(i), len(logDict.keys())))
        if i > LOGLIMIT:
            break
        proc = Popen('git log --pretty=format:"%%s" %s -1' % key,
                     shell=True,
                     stdout=PIPE)
        body = "".join(proc.stdout.readlines())
        logDict[key]["body"] = body

        proc = Popen('git log --numstat %s -1 --pretty=format:%%an' % key,
                     shell=True,
                     stdout=PIPE)
        diff = proc.stdout.readlines()
        files = {}
        if not diff:
            logDict.pop(key)
            continue
        authorName = diff[0].strip()
        if authorName not in authorDict.keys():
            authorDict[authorName] = {}
            authorDict[authorName]["added"] = 0
            authorDict[authorName]["removed"] = 0

        for line in diff[1:]:
            line = line.strip().split("\t")
            try:
                added = int(line[0])
                removed = int(line[1])

                authorDict[authorName]["added"] += added
                authorDict[authorName]["removed"] += removed
            except ValueError:
                added = removed = "N/A"

            file = line[2]

            files[file] = {}
            files[file]["added"] = added
            files[file]["removed"] = removed
    
        logDict[key]["diff"] = files
             
        i += 1

    totalCommits = len(log)
    browser.append("Read %d commits" % totalCommits)

    i = 1
    for key in logDict.keys():
        if i > LOGLIMIT:
            break

        totalAdded = 0
        totalRemoved = 0
        for file in logDict[key]["diff"].keys():
            try:
                totalAdded += int(logDict[key]["diff"][file]["added"])
                totalRemoved += int(logDict[key]["diff"][file]["removed"])

                if file not in fileDict.keys():
                    fileDict[file] = {}
                    fileDict[file]["added"] = 0
                    fileDict[file]["removed"] = 0
   
                fileDict[file]["added"] += int(logDict[key]["diff"][file]["added"])
                fileDict[file]["removed"] += int(logDict[key]["diff"][file]["removed"])

            except ValueError:
                pass

        for file in logDict[key]["diff"].keys():
            addedLines = 0
            removedLined = 0
            try:
                addedLines = int(logDict[key]["diff"][file]["added"])
                removedLines = int(logDict[key]["diff"][file]["removed"])
            except ValueError:
                pass

            cursor.execute('INSERT INTO fileTable VALUES (null, ?, ?, ?, ?, ?, ?, ?, ? )', (projectName, projectVersion, key, \
                                                                                            logDict[key]["time"], logDict[key]["author"], \
                                                                                            file, addedLines, removedLines))

        cursor.execute('INSERT INTO commitTable VALUES (null, ?, ?, ?, ?, ?, ?)', (projectName, projectVersion, key, \
                                                                                      logDict[key]["author"], logDict[key]["time"], \
                                                                                      "\0".join(logDict[key]["body"].split("\n"))))


        i += 1

    for author in authorDict.keys():
        cursor.execute('INSERT INTO authorTable VALUES (null, ?, ?, ?, ?)' , (projectName, projectVersion, author, \
                                                                              authorDict[author]["added"] + authorDict[author]["removed"]))

    cursor.execute('INSERT INTO projectTable VALUES (null, ?, ?, ?, ?, ?, ?)', (projectName, projectVersion, startDate, endDate, numberOfFiles, "0"))

    connection.commit()
    os.chdir(defaultDirectory)
    
def getMercurialRepo(serverUrl, projectDirectory, browser):    
    browser.clear()    
        
    global defaultDirectory
    defaultDirectory = os.getcwd()

    if os.path.exists(projectDirectory):
        browser.append("Destination already exists!... Will UPDATE:\n\n%s" % serverUrl + "\n\nHold on please...\n\n\n")
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

        os.chdir(projectDirectory)
        proc = Popen("hg revert -r tip --all", shell=True, stdout=PIPE)
        while True:
            out = proc.stdout.readline()
            if out == '' and proc.poll() != None:
                break
            if out != '':
                out = out.replace('\n', '')
                browser.append(out)
                QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
                
        proc = Popen("hg pull -u -v", shell=True, stdout=PIPE)
        while True:
            out = proc.stdout.readline()
            if out == '' and proc.poll() != None:
                break
            if out != '':
                out = out.replace('\n', '')
                browser.append(out)
                QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
    
    else:
        os.system("mkdir " + projectDirectory)
        os.chdir(projectDirectory)
	browser.append("Starting to CHECKOUT:\n\n%s" % serverUrl + "\n\nHold on please...\n\n\n")
        QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)
        
        proc = Popen("hg clone %s" % serverUrl, shell=True, stdout=PIPE)
        while True:
            out = proc.stdout.readline()
            if out == '' and proc.poll() != None:
                break
            if out != '':
                out = out.replace('\n', '')
                browser.append(out)
                QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents)

    os.chdir(defaultDirectory)

def parseMercurialLog(projectName, projectVersion, filePath, browser):
    browser.clear()

    if not os.path.exists(filePath):
        browser.append("%s does not exist" % filePath)
        return

    global defaultDirectory
    defaultDirectory = os.getcwd()    
    #get log here...
